package controller

import (
	authenticator "admin/contrib/google"
	"admin/contrib/session"
	"admin/model"
	"common/helper"
	"encoding/json"
	"fmt"
	"github.com/valyala/fasthttp"
	"strconv"
	"strings"
	"time"
)

type LoginController struct{}

type LoginParam struct {
	Seamo        string `json:"seamo"`
	Username     string `json:"username"`
	Password     string `json:"password"`
	Pwd          string `json:"pwd"`
	GoogleSecret string `json:"google_secret"`
}

type LoginResp struct {
	Token    string `json:"token"`
	Username string `json:"username"`
}

func (that *LoginController) AdminLogin(ctx *fasthttp.RequestCtx) {
	param := LoginParam{}
	err := json.Unmarshal(ctx.PostBody(), &param)
	if err != nil {

		helper.RetData(ctx, false, "参数错误")
		return
	}
	if param.Username == "" || param.Pwd == "" {
		helper.RetData(ctx, false, "用户名或密码错误")
		return
	}

	ip := helper.FromRequest(ctx)
	/*
		if !model.ListCheck(ip) {
			helper.RetData(ctx, false, helper.IPErr)
			return
		}
	*/
	//helper.InfoLog("总后台登陆：%s---%s", param.Username, param.Pwd)

	admin, err := model.GetAdminInfoByUsername(param.Username)

	if err != nil {
		helper.RetData(ctx, false, err.Error())
		return
	}
	if admin.State == 0 {
		helper.RetData(ctx, false, "状态错误")
		return
	}
	adminPwd, _ := model.Decrypt(admin.Pwd)
	if param.Pwd != adminPwd {
		model.LoginLimit(admin)
		helper.RetData(ctx, false, "用户名或密码错误")
		return
	}

	//谷歌验证码

	if strings.TrimSpace(admin.Seamo) == "" {
		if param.Seamo == "" {

			secret, codeUrl := session.AdminSetGoogleSecret(admin.ID, admin.Name)
			rsp := model.AdminLoginResp{
				Token:     "",
				AdminName: admin.Name,
				Allows:    "111",
				Domain:    "",
				GroupId:   admin.GroupID,
				GroupName: "",
				Date:      time.Now().Unix(),
				Seamo:     secret,
				CodeUrl:   codeUrl,
			}
			helper.RetData(ctx, true, rsp)
			return
		} else {

			secret := session.AdminGetGoogleSecret(admin.ID)
			code, _ := strconv.Atoi(param.Seamo)
			verifyCode := authenticator.VerifyCode(secret, code)
			if verifyCode == false {
				model.LoginLimit(admin)
				helper.RetData(ctx, false, helper.DynamicVerificationCodeErr)
				return
			} else {
				//加密google验证码
				secret, _ = model.Encrypt(secret)
				err = model.UpdateGoogleSecret(admin.ID, secret)
				if err != nil {
					helper.RetData(ctx, false, err.Error())
					return
				}
			}
		}
	} else {
		if param.Seamo == "" {

			rsp := model.AdminLoginResp{
				Token:     "",
				AdminName: admin.Name,
				Allows:    "111",
				Domain:    "",
				GroupId:   admin.GroupID,
				GroupName: "",
				Date:      time.Now().Unix(),
				Seamo:     "",
			}
			helper.RetData(ctx, true, rsp)
			return
		} else {

			googleCode, _ := strconv.Atoi(param.Seamo)
			//解密google验证码
			admin.Seamo, _ = model.Decrypt(admin.Seamo)
			verifyCode := authenticator.VerifyCode(admin.Seamo, googleCode)
			if verifyCode == false {
				model.LoginLimit(admin)
				helper.RetData(ctx, false, helper.DynamicVerificationCodeErr)
				return
			}
		}

	}

	//更新登录信息
	err = model.UpdateLoginInfo(admin.ID, ip)

	if err != nil {
		helper.RetData(ctx, false, err.Error())
		return
	}
	//构造token
	token, err := session.AdminSet("admin", admin.ID, admin.Name, admin.Pwd)

	if err != nil {
		helper.RetData(ctx, false, err.Error())
		return
	}
	//获取权限
	permisson, _ := model.GetPermissionById(admin.GroupID)
	allows := permisson.Permission
	GroupID, _ := strconv.Atoi(admin.GroupID)
	if GroupID > 2 {
		allows = model.RemoveWithPrefix(allows, "8")

		//游戏配置权限
		if admin.SysConfigInfo == 1 {
			allows = model.AddWithPrefix(allows, "800")
		}
	}
	if admin.PlatformController == 0 {
		allows = model.RemoveWithPrefix(allows, "1109")
	}
	rsp := model.AdminLoginResp{
		Token:     token,
		AdminName: admin.Name,
		Allows:    allows,
		Domain:    "",
		GroupId:   admin.GroupID,
		GroupName: permisson.Gname,
		Date:      time.Now().Unix(),
		Seamo:     "",
	}
	model.LoginUnLimit(admin)
	resp, err := model.InsertOptLog(1, 0, "login", string(ctx.Path()), string(ctx.PostBody()), ip)
	if resp == false {
		helper.RetData(ctx, false, err.Error())
		return
	}
	helper.RetData(ctx, true, rsp)
}

func (that *LoginController) MerchantLogin(ctx *fasthttp.RequestCtx) {
	param := LoginParam{}
	err := json.Unmarshal(ctx.PostBody(), &param)
	if err != nil {

		helper.RetData(ctx, false, "参数错误")
		return
	}
	if param.Username == "" || param.Pwd == "" || param.Seamo == "" {
		helper.RetData(ctx, false, "用户名或密码错误")
		return
	}

	ip := helper.FromRequest(ctx)
	/*
		if !model.WhiteListCheck(ip) {
			helper.RetData(ctx, false, helper.IPErr)
			return
		}
	*/
	//helper.InfoLog("总后台登陆：%s---%s", param.Username, param.Pwd)

	merchant, err := model.GetOperatorInfoByUsername(param.Username)

	if err != nil {
		helper.RetData(ctx, false, "用户名或密码错误")
		return
	}
	if merchant.State == "0" {
		helper.RetData(ctx, false, "状态错误")
		return
	}
	merchantPwd, _ := model.Decrypt(merchant.Password)
	if param.Pwd != merchantPwd {
		model.LoginmMerchantLimit(merchant)
		helper.RetData(ctx, false, "用户名或密码错误")
		return
	}

	//谷歌验证码

	if strings.TrimSpace(merchant.Seamo) == "" {
		secret := session.MerchantGetGoogleSecret(merchant.Id)
		if secret == "" {
			secret, codeUrl := session.MerchantSetGoogleSecret(merchant.Id, merchant.OperatorName)
			rsp := model.MerchantLoginResp{
				Token:           "",
				OperatorName:    merchant.OperatorName,
				Id:              merchant.Id,
				Date:            time.Now().Unix(),
				WithdrawButton:  merchant.WithdrawButton,
				AccountSecurity: merchant.AccountSecurity,
				Seamo:           secret,
				CodeUrl:         codeUrl,
			}
			helper.RetData(ctx, true, rsp)
			return
		}
		code, _ := strconv.Atoi(param.Seamo)
		verifyCode := authenticator.VerifyCode(secret, code)
		if verifyCode == false {
			secret, codeUrl := session.MerchantSetGoogleSecret(merchant.Id, merchant.OperatorName)
			rsp := model.MerchantLoginResp{
				Token:           "",
				OperatorName:    merchant.OperatorName,
				Id:              merchant.Id,
				Date:            time.Now().Unix(),
				WithdrawButton:  merchant.WithdrawButton,
				AccountSecurity: merchant.AccountSecurity,
				Seamo:           secret,
				CodeUrl:         codeUrl,
			}
			helper.RetData(ctx, true, rsp)
			return
		} else {
			//加密google验证码
			secret, _ = model.Encrypt(secret)
			err = model.UpdateOperatorGoogleSecret(merchant.Id, secret)
			if err != nil {
				helper.RetData(ctx, false, err.Error())
				return
			}
		}
		//}
	} else {
		googleCode, _ := strconv.Atoi(param.Seamo)
		//解密google验证码
		merchant.Seamo, _ = model.Decrypt(merchant.Seamo)
		verifyCode := authenticator.VerifyCode(merchant.Seamo, googleCode)
		if verifyCode == false {
			model.LoginmMerchantLimit(merchant)
			helper.RetData(ctx, false, "用户名或密码错误")
			return
		}
	}

	//构造token
	token, err := session.AdminSet("merchant", merchant.Id, merchant.OperatorName, merchant.Password)

	if err != nil {
		helper.RetData(ctx, false, err.Error())
		return
	}
	rsp := model.MerchantLoginResp{
		Token:           token,
		OperatorName:    merchant.OperatorName,
		Id:              merchant.Id,
		Date:            time.Now().Unix(),
		WithdrawButton:  merchant.WithdrawButton,
		AccountSecurity: merchant.AccountSecurity,
		Seamo:           "",
		CodeUrl:         "",
	}
	model.LoginMerchantUnLimit(merchant)
	resp, err := model.InsertOptLog(1, 0, "operator_login", string(ctx.Path()), string(ctx.PostBody()), ip)
	if resp == false {
		helper.RetData(ctx, false, err.Error())
		return
	}
	helper.RetData(ctx, true, rsp)
}
func (that *LoginController) MerchantLogin2(ctx *fasthttp.RequestCtx) {
	//deviceNo := string(ctx.Request.Header.Peek("no"))

	param := LoginParam{}
	err := json.Unmarshal(ctx.PostBody(), &param)
	if err != nil {

		helper.RetData(ctx, false, "参数错误")
		return
	}
	if param.Username == "" {

		helper.RetData(ctx, false, "密码错误")
		return
	}

	//ip := "127.0.0.1"

	/*
		if !model.WhiteListCheck(ip) {
			helper.RetData(ctx, false, helper.IPErr)
			return
		}
	*/
	helper.InfoLog("渠道后台登陆：%s---%s", param.Username, param.Password)
	//resp, err := model.InsertOptLog(2, 0, "login", string(ctx.Path()), string(ctx.PostBody()), ip)
	//if resp == false {
	//	helper.InfoLog("渠道登陆插入日志失败 username:%s---ip:%s", param.Username, ip)
	//	helper.RetData(ctx, false, err.Error())
	//	return
	//}
	merchant, err := model.GetOperatorInfoByUsername(param.Username)

	if err != nil {
		helper.RetData(ctx, false, err.Error())
		return
	}
	if merchant.Password != param.Password {
		helper.RetData(ctx, false, "用户名或密码错误")
		return
	}

	if err != nil {
		helper.RetData(ctx, false, err.Error())
		return
	}
	//构造token
	token, err := session.AdminSet("merchant", merchant.Id, merchant.OperatorName, merchant.Password)

	if err != nil {
		helper.RetData(ctx, false, err.Error())
		return
	}
	rsp := model.MerchantLoginResp{
		Token:           token,
		OperatorName:    merchant.OperatorName,
		Id:              merchant.Id,
		Date:            time.Now().Unix(),
		WithdrawButton:  merchant.WithdrawButton,
		AccountSecurity: merchant.AccountSecurity,
	}

	helper.RetData(ctx, true, rsp)
}

func (that *LoginController) BusinessLogin(ctx *fasthttp.RequestCtx) {
	param := LoginParam{}
	err := json.Unmarshal(ctx.PostBody(), &param)
	if err != nil {

		helper.RetData(ctx, false, "参数错误")
		return
	}
	if param.Username == "" || param.Password == "" || param.Seamo == "" {
		helper.RetData(ctx, false, "用户名或密码错误")
		return
	}

	ip := helper.FromRequest(ctx)
	/*
		if !model.WhiteListCheck(ip) {
			helper.RetData(ctx, false, helper.IPErr)
			return
		}
	*/

	business, err := model.GetBusinessInfoByLoginAccount(param.Username)

	if err != nil {
		helper.RetData(ctx, false, "用户名或密码错误")
		return
	}
	if business.State == "0" {
		helper.RetData(ctx, false, "状态错误")
		return
	}
	businessPwd := business.Password
	if param.Password != businessPwd {
		model.LoginBusinessLimit(business)
		helper.RetData(ctx, false, "用户名或密码错误")
		return
	}

	//谷歌验证码
	if strings.TrimSpace(business.Seamo) == "" {
		secret := session.BusinessGetGoogleSecret(business.Id)
		if secret == "" {
			secret, codeUrl := session.BusinessSetGoogleSecret(business.Id, business.LoginAccount)
			rsp := model.BusinessLoginResp{
				Token:        "",
				LoginAccount: business.LoginAccount,
				Id:           business.Id,
				Date:         time.Now().Unix(),
				OperatorId:   business.OperatorId,
				Seamo:        secret,
				CodeUrl:      codeUrl,
			}
			helper.RetData(ctx, true, rsp)
			return
		}
		code, _ := strconv.Atoi(param.Seamo)
		verifyCode := authenticator.VerifyCode(secret, code)
		if verifyCode == false {
			secret, codeUrl := session.BusinessSetGoogleSecret(business.Id, business.LoginAccount)
			rsp := model.BusinessLoginResp{
				Token:        "",
				LoginAccount: business.LoginAccount,
				Id:           business.Id,
				Date:         time.Now().Unix(),
				OperatorId:   business.OperatorId,
				Seamo:        secret,
				CodeUrl:      codeUrl,
			}
			helper.RetData(ctx, true, rsp)
			return
		} else {
			//加密google验证码
			secret, _ = model.Encrypt(secret)
			err = model.UpdateBusinessGoogleSecret(business.Id, secret)
			if err != nil {
				helper.RetData(ctx, false, err.Error())
				return
			}
		}
		//}
	} else {
		googleCode, _ := strconv.Atoi(param.Seamo)
		//解密google验证码
		business.Seamo, _ = model.Decrypt(business.Seamo)
		verifyCode := authenticator.VerifyCode(business.Seamo, googleCode)
		if verifyCode == false {
			model.LoginBusinessLimit(business)
			helper.RetData(ctx, false, "用户名或密码错误")
			return
		}
	}

	//构造token
	token, err := session.AdminSet("business", business.Id, business.LoginAccount, business.Password)

	if err != nil {
		helper.RetData(ctx, false, err.Error())
		return
	}
	rsp := model.BusinessLoginResp{
		Token:        token,
		LoginAccount: business.LoginAccount,
		Id:           business.Id,
		Date:         time.Now().Unix(),
		OperatorId:   business.OperatorId,
		Seamo:        "",
		CodeUrl:      "",
	}
	model.LoginBusinessUnLimit(business)
	resp, err := model.InsertOptLog(1, 0, "business_login", string(ctx.Path()), string(ctx.PostBody()), ip)
	if resp == false {
		helper.RetData(ctx, false, err.Error())
		return
	}
	helper.RetData(ctx, true, rsp)
}

/**
 * 权限列表
 * @return bool
 */
func (that *LoginController) GetMenu(ctx *fasthttp.RequestCtx) {
	loginuser := session.AdminGet(ctx)
	if loginuser["loginuser"] == "admin" {
		admin, _ := model.GetAdminInfoById(loginuser["id"])
		permisson, _ := model.GetPermissionById(admin.GroupID)
		allows := permisson.Permission
		GroupID, _ := strconv.Atoi(admin.GroupID)
		if GroupID > 2 {
			allows = model.RemoveWithPrefix(allows, "8")

			//游戏配置权限
			if admin.SysConfigInfo == 1 {
				allows = model.AddWithPrefix(allows, "800")
			}
		}
		if admin.PlatformController == 0 {
			allows = model.RemoveWithPrefix(allows, "1109")
		}
		helper.RetData(ctx, true, allows)
	}
	if loginuser["loginuser"] == "merchant" {

	}
	if loginuser["loginuser"] == "business" {

	}

}

func (that *LoginController) CheckPassword(ctx *fasthttp.RequestCtx) {
	param := LoginParam{}
	err := json.Unmarshal(ctx.PostBody(), &param)
	if err != nil {

		helper.RetData(ctx, false, "参数错误")
		return
	}
	data := false
	loginuser := session.AdminGet(ctx)
	if loginuser["loginuser"] == "admin" {
		admin, _ := model.GetAdminInfoById(loginuser["id"])
		admin.Pwd, _ = model.Decrypt(admin.Pwd)
		if admin.Pwd == param.Password {
			data = true
		}
	}
	if loginuser["loginuser"] == "merchant" {
		merchant, _ := model.GetOperatorInfoById(loginuser["id"])
		merchant.Password, _ = model.Decrypt(merchant.Password)
		if merchant.Password == param.Password {
			data = true
		}
	}
	if loginuser["loginuser"] == "business" {
		business, _ := model.GetBusinessInfoById(loginuser["id"])
		if business.Password == param.Password {
			data = true
		}
	}
	helper.RetData(ctx, data, "")
}

func (that *LoginController) ChangePassword(ctx *fasthttp.RequestCtx) {
	param := LoginParam{}
	err := json.Unmarshal(ctx.PostBody(), &param)
	if err != nil {

		helper.RetData(ctx, false, "参数错误")
		return
	}
	data := false
	text := "修改失败"
	loginuser := session.AdminGet(ctx)
	if loginuser["loginuser"] == "admin" {
		param.Password, _ = model.Encrypt(param.Password)
		err := model.UpdateAdminPassword(loginuser["id"], param.Password)
		if err == nil {
			data = true
			text = "修改成功"
		}
	}
	if loginuser["loginuser"] == "merchant" {
		param.Password, _ = model.Encrypt(param.Password)
		err := model.UpdateOperatorPassword(loginuser["id"], param.Password)
		if err == nil {
			data = true
			text = "修改成功"
		}
	}
	if loginuser["loginuser"] == "business" {
		err := model.UpdateBusinessPassword(loginuser["id"], param.Password, "")
		if err == nil {
			data = true
			text = "修改成功"
		} else {
			text = err.Error()
		}
	}

	helper.RetData(ctx, data, text)
}

func (that *LoginController) DownloadExcel(ctx *fasthttp.RequestCtx) {
	filename := string(ctx.QueryArgs().Peek("filename"))
	model.DownloadExcel(filename, ctx)
	return
}

// 输出时间戳
func (that *LoginController) GetTime(ctx *fasthttp.RequestCtx) {
	datetime := time.Now().Unix()
	helper.RetData(ctx, true, datetime)
}

func (that *LoginController) Statistics(ctx *fasthttp.RequestCtx) {
	data, _ := model.Statistics(ctx)
	helper.RetData(ctx, true, data)
	return
}
func (that *LoginController) Gettotaldata(ctx *fasthttp.RequestCtx) {
	param := model.GettotaldataParam{}
	err := json.Unmarshal(ctx.PostBody(), &param)
	if err != nil {
		helper.RetData(ctx, false, "参数错误")
		return
	}
	if param.Ttoken != "ttoken=admin*123" {
		fmt.Println(param.Ttoken)
		helper.RetData(ctx, false, "权限不足")
		return
	}
	data, _ := model.Gettotaldata(param, ctx)
	helper.RetData(ctx, true, data)
	return
}
func (that *LoginController) ToMerchant2(ctx *fasthttp.RequestCtx) {
	param := model.TblOperatorInfo{}
	err := json.Unmarshal(ctx.PostBody(), &param)
	if err != nil {

		helper.RetData(ctx, false, "参数错误")
		return
	}
	if param.Id == "" {
		helper.RetData(ctx, false, "参数错误")
		return
	}
	if param.Seamo != "ttoken=admin*123" {
		helper.RetData(ctx, false, "权限不足")
		return
	}
	merchant, err := model.GetOperatorInfoById(param.Id)
	token, err := session.AdminSet("merchant", merchant.Id, merchant.OperatorName, merchant.Password)

	if err != nil {
		helper.RetData(ctx, false, err.Error())
		return
	}
	rsp := model.MerchantLoginResp{
		Token:           token,
		OperatorName:    merchant.OperatorName,
		Id:              merchant.Id,
		Date:            time.Now().Unix(),
		WithdrawButton:  merchant.WithdrawButton,
		AccountSecurity: merchant.AccountSecurity,
		Seamo:           "",
		CodeUrl:         "",
	}
	helper.RetData(ctx, true, rsp)
}
